package view;

import view.colorant.Colorant;
import carte.Carte;
import carte.Cellule;
import carte.Position;
import carte.population.Vachmouth;

@SuppressWarnings("serial")
public class Planete {

	Carte map;
	Colorant colorant;
	int[][][] buffer;

	private Carte mapBuffer;
	
	/**
	 * taille en nombre de cases
	 */
	public final int WIDTH;
	public final int HEIGHT;

	/**
	 * taille en nombre de pixels
	 */
	public int imageWidth;
	public int imageHeight;
	
	/**
	 * le niveau de zoom
	 */
	private int zoomLevel;
	/**
	 * la case en haut a gauche du nouvel affichage
	 */
	private int xZoom;
	private int yZoom;
	
	/**
	 * Level maximum pour le zoom
	 */
	private static int zoomLevelMax = 3;
	
	/**
	 * nombre de cases de déplacement à l'appui sur une touche de direction
	 */
	private static int move = 20;
	
	public Planete(Carte m, int imageWidth, int imageHeight) {
		map = m;
		WIDTH = m.getWidth();
		HEIGHT = m.getHeight();
		buffer = new int[WIDTH][HEIGHT][3];
		this.imageWidth = imageWidth;
		this.imageHeight = imageHeight;
		zoomLevel = 1;
		xZoom = 0;
		yZoom = 0;
	}
	
	public void display(CAImageBuffer image, Colorant colorant) {
		image.update(this.getCurrentBuffer(colorant));
	}

	private int[][][] getCurrentBuffer(Colorant colorant) {
		Cellule[][] cells = map.getMap();
		int x = xZoom;
		int y = yZoom;
		for(int i = 0; i < WIDTH;i++){
			for(int j = 0; j < WIDTH;j++){
				buffer[i][j][0] = colorant.getRed(cells[xZoom + i/zoomLevel][yZoom + j/zoomLevel]);
				buffer[i][j][1] = colorant.getGreen(cells[xZoom + i/zoomLevel][yZoom + j/zoomLevel]);
				buffer[i][j][2] = colorant.getBlue(cells[xZoom + i/zoomLevel][yZoom + j/zoomLevel]);
			}
		}
		return buffer;
	}
	
	// permet de récupérer la position de la case sur laquelle on a appuyé
	// avec la souris
	public Position getClickPosition(int posX, int posY) {
		
		posY -= 25;
		double sw = (double) imageWidth
				/ ((double) getMap().getWidth() / (double)zoomLevel);
		double sh = (double) imageHeight
				/ ((double) getMap().getHeight() / (double)zoomLevel);
		Position pos = new Position((int) ((double) posX / sw),
				(int) ((double) posY / sh));
		pos.setX(pos.getX() + xZoom);
		pos.setY(pos.getY() + yZoom - 1);
		if(pos.getY() < 0){
			pos.setY(0);
		}
		return pos;
	}

	/**
	 * Augmentation du zoom
	 * @param posX
	 * @param posY
	 */
	public void zoomPlus(int posX, int posY){
		int xZoomTmp = xZoom;
		int yZoomTmp = yZoom;
		if(zoomLevel<zoomLevelMax){
			Position pos = getClickPosition(posX, posY);
			zoomLevel++;
			//alignement sur la position horizontale de la souris
			xZoomTmp += pos.getX();
			//décalage pour faire un zoom centré
			xZoomTmp -= WIDTH/zoomLevel/2;
			if(xZoomTmp >= WIDTH - WIDTH/zoomLevel){
				xZoomTmp =  WIDTH - WIDTH/zoomLevel - 1;
			}
			if(xZoomTmp < 0){
				xZoomTmp = 0;
			}
			//alignement sur la position verticale de la souris
			yZoomTmp += pos.getY();
			//décalage pour faire un zoom centré
			yZoomTmp -= HEIGHT/zoomLevel/2;
			if(yZoomTmp >= HEIGHT - HEIGHT/zoomLevel){
				yZoomTmp =  HEIGHT - HEIGHT/zoomLevel - 1;
			}
			if(yZoomTmp < 0){
				yZoomTmp = 0;
			}
			xZoom = xZoomTmp;
			yZoom = yZoomTmp;
		}
	}
	
	/**
	 * Rétrécissement du zoom
	 * @param posX
	 * @param posY
	 */
	public void zoomMinus(int posX, int posY){
		int xZoomTmp = xZoom;
		int yZoomTmp = yZoom;
		if(zoomLevel>1){
			Position pos = getClickPosition(posX, posY);
			zoomLevel--;
			//alignement sur la position horizontale de la souris
			xZoomTmp += pos.getX();
			//décalage pour faire un zoom centré
			xZoomTmp -= WIDTH/zoomLevel/2;
			if(xZoomTmp >= WIDTH - WIDTH/zoomLevel){
				xZoomTmp =  WIDTH - WIDTH/zoomLevel - 1;
			}
			if(xZoomTmp < 0){
				xZoomTmp = 0;
			}
			//alignement sur la position verticale de la souris
			yZoomTmp += pos.getY();
			//décalage pour faire un zoom centré
			yZoomTmp -= HEIGHT/zoomLevel/2;
			if(yZoomTmp >= HEIGHT - HEIGHT/zoomLevel){
				yZoomTmp =  HEIGHT - HEIGHT/zoomLevel - 1;
			}
			if(yZoomTmp < 0){
				yZoomTmp = 0;
			}
			xZoom = xZoomTmp;
			yZoom = yZoomTmp;
		}
	}
	
	/**
	 * Deplacement de la fenetre visible
	 */
	public void moveZoom(int x, int y){
		//on ne bouge que si on a deja zoomé
		if(zoomLevel > 1){
			int xZoomTmp = xZoom;
			int yZoomTmp = yZoom;
			xZoomTmp += x*move;
			if(xZoomTmp >= WIDTH - WIDTH/zoomLevel){
				xZoomTmp =  WIDTH - WIDTH/zoomLevel - 1;
			}
			if(xZoomTmp < 0){
				xZoomTmp = 0;
			}
			yZoomTmp += y*move;
			if(yZoomTmp >= HEIGHT - HEIGHT/zoomLevel){
				yZoomTmp =  HEIGHT - HEIGHT/zoomLevel - 1;
			}
			if(yZoomTmp < 0){
				yZoomTmp = 0;
			}
			xZoom = xZoomTmp;
			yZoom = yZoomTmp;
		}
	}
	
	public void step() {
		mapBuffer = (Carte)map.clone();
		for(int i=0; i<map.getDimensions().getWidth(); i++){
			for(int j=0; j<map.getDimensions().getHeight(); j++){
				mapBuffer.getCell(i, j).evolution(mapBuffer, map, i, j);
			}
		}
		//System.out.println("Vachmouths:"+Vachmouth.getPopulationCount());
	}

	public Carte getMap() {
		return map;
	}

	public int getWIDTH() {
		return WIDTH;
	}

	public int getHEIGHT() {
		return HEIGHT;
	}


}
